package cn.kstry.demo.service;

import cn.kstry.framework.core.annotation.TaskComponent;
import cn.kstry.framework.core.annotation.TaskInstruct;
import cn.kstry.framework.core.annotation.TaskService;
import cn.kstry.framework.core.bus.InstructContent;
import cn.kstry.framework.core.bus.ScopeDataOperator;
import com.alibaba.fastjson.JSON;
import lombok.Data;
import org.apache.commons.beanutils.PropertyUtils;

import java.util.Comparator;
import java.util.List;
import java.util.Optional;

/**
 * 简单定义，用来掩演示，不能直接用在生产环境，有很多异常情况未考虑
 */
@SuppressWarnings("all")
@TaskComponent(name = "InstructService")
public class InstructService {

    @TaskInstruct(name = "sort")
    @TaskService(name = "instruct-service-sort")
    public void sort(InstructContent instructContent, ScopeDataOperator operator) {
        SortContent sortContent = JSON.parseObject(instructContent.getContent(), SortContent.class);
        Optional<Object> dataOptional = operator.getData(sortContent.getSource());
        if (!dataOptional.isPresent() || !(dataOptional.get() instanceof List)) {
            return;
        }

        List<?> list = (List<?>) dataOptional.get();
        if (sortContent.asc) {
            list.sort(Comparator.comparing(o -> {
                try {
                    return (Comparable) PropertyUtils.getProperty(o, sortContent.getSortFieldName());
                } catch (Exception e) {
                    return null;
                }
            }));
        } else {
            list.sort(Comparator.comparing(o -> {
                try {
                    return (Comparable) PropertyUtils.getProperty(o, sortContent.getSortFieldName());
                } catch (Exception e) {
                    return null;
                }
            }).reversed());
        }
        operator.setData(sortContent.getTarget(), list);
    }

    @Data
    public static class SortContent {

        /**
         * 要排序数据的位置
         */
        private String source;

        /**
         * 根据对象的哪个字段来排序
         */
        private String sortFieldName;

        /**
         * 排序后的集合放在什么地方
         */
        private String target;

        /**
         * 是否是升序
         */
        private boolean asc;
    }
}
